package com.dpwgc.demo.interceptor;

import com.alibaba.fastjson.JSON;
import com.dpwgc.demo.mapper.AdminMapper;
import com.dpwgc.demo.model.AccessLog;
import com.dpwgc.demo.model.Admin;
import com.dpwgc.demo.utils.DateUtil;
import com.dpwgc.demo.utils.RedisUtil;
import com.dpwgc.demo.utils.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;


/**
 * 登录验证拦截
 */
@Controller
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    DateUtil dateUtil;

    @Autowired
    AdminMapper adminMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        /**
         * 请求头部：两个参数
         * @param id 用户id
         * @param token 登录令牌
         */
        String id = request.getHeader("id");//用户id
        String token = request.getHeader("token");//token令牌

        String ip = request.getRemoteAddr();//获取访问者的IP地址
        String uri = request.getRequestURI();//获取访问者请求的控制器路径记录

        ResultUtil resultUtil = new ResultUtil();

        //如果请求头部id值为空
        if (id == null){
            resultUtil.setMsg("请登陆后访问");
            resultUtil.setCode(440);
            response.setCharacterEncoding("UTF-8");
            PrintWriter writer = response.getWriter();
            writer.write(JSON.toJSONString(resultUtil));
            writer.flush();
            return false;
        }

        //从redis中取出对应token令牌，进行匹配
        Object resToken = redisUtil.get(id);
        String strToken = String.valueOf(resToken);

        //匹配token令牌
        if (strToken.equals(token)){

            /**
             * 访问日志记录
             */
            AccessLog accessLog = new AccessLog();
            accessLog.setUserId(Integer.parseInt(id));
            accessLog.setIp(ip);
            accessLog.setUri(uri);
            accessLog.setLogTime(dateUtil.getDateTime());
            try {
                System.out.println("\033[" + 34 + ";7m" + "访问者IP:" + ip + " 请求路径:" + uri + "\033[0m");

            }catch (Exception e){
                System.err.println(e);
            }

            /**
             * 如果是管理员相关操作
             * 则进行群组管理员权限校验
             */
            if(uri.split("/")[1].equals("Admin")){

                //获取请求参数的key
                Enumeration<String> keyMap = request.getParameterNames();
                HashMap<String, String> param = new HashMap<String, String>();
                //枚举key，获取请求参数的value
                while (keyMap.hasMoreElements()) {
                    String key = keyMap.nextElement();
                    String value = request.getParameter(key);
                    //添加请求参数
                    param.put(key, value);
                }
                //通过用户id与群组id确认用户是否有群组管理员权限
                Admin admin = adminMapper.checkAdminLv(Integer.parseInt(id),(Integer.parseInt(param.get("groupId"))));
                //确认权限
                if(admin != null && admin.getLv()>0){
                    return true;
                }
                //无权限
                else {
                    resultUtil.setMsg("权限不足");
                    resultUtil.setCode(300);
                    response.setCharacterEncoding("UTF-8");
                    PrintWriter writer = response.getWriter();
                    writer.write(JSON.toJSONString(resultUtil));
                    writer.flush();
                    return false;
                }
            }
            return true;

        }else {
            resultUtil.setMsg("请登陆后访问");
            resultUtil.setCode(440);
            response.setCharacterEncoding("UTF-8");
            PrintWriter writer = response.getWriter();
            writer.write(JSON.toJSONString(resultUtil));
            writer.flush();
            return false;
        }
    }
}
